###################################################################### Product:      KnowledgeEngine (Plone Edition)## File:         AssessmentAction.py## Copyright:    Copyright (c) 2006, Faulkner Technologies## Author:       Brian Oliver## Description:  This file defines the AssessmentAction class, a simple#               named 'container' of Actions that may be performed#               on assessments.#   #               Assessment Actions may be listed together with each#               assessment in an assessment explorer#               # See Also:     Element, Action#####################################################################

####################################################################### Knowledge Engine Library Importsfrom Products.KnowledgeEngine.Common import *from Products.KnowledgeEngine.Core import *from Products.KnowledgeEngine.Action import *from Products.KnowledgeEngine.Element import Element, ElementInfofrom Products.KnowledgeEngine.PropertyDefinition import PropertyDefinitionfrom Products.KnowledgeEngine.EventDefinition import *from Products.KnowledgeEngine.Model.Model import Modelfrom Products.KnowledgeEngine.PermissionDefinition import *
from Products.KnowledgeEngine.KERLProcessor import *
####################################################################### Zope Library Importsfrom Globals import DTMLFilefrom App.ImageFile import ImageFile

####################################################################### Python Library Imports# (none)
####################################################################### AssessmentActionInfo Class Definitionclass AssessmentActionInfo(ElementInfo):    """        Defines the class info methods, defining information about        the class without needing an instance of the class    """        #---------------------------------------------------------------#        def getClassName(self):        """            Returns the name of the class for which             we are providing information.        """        return "AssessmentAction"

    #---------------------------------------------------------------#

    def getDisplayName(self):        """            Return a friendly name for the class instances            (this is used for displaying in lists etc)        """            return "Assessment Action"            #---------------------------------------------------------------#

    def getIdentityType(self):        """            Return the identity type.          """                return "assessmentaction"            #---------------------------------------------------------------#        def getClassIcon(self):        """            Return the appropriate icon file for the class.        """                return ImageFile('skins/AssessmentAction_icon.gif', globals())

    #---------------------------------------------------------------#

    def isContainer(self):        """            Returns if the instance is providing folderish/container            services.                        Override an return true if the instance is to be            a container for other instances.                        NOTE: all instances support "events" so there is no            need to return true if you require "event" support.        """
        #AssessmentActions are containers for Actions!        return true            #---------------------------------------------------------------#

    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):        """            ABSTRACT: Returns if class instances (instance) is permitted in             the specified container (containerInstance)                        NOTE: This is from this class' instance perspective.        """                #DEFAULT RULE: AssessmentActions are only permitted in Models        return containerClassInfo.isInstanceOf('Model') or containerClassInfo.isInstanceOf('Repository') 

    #---------------------------------------------------------------#

    def isChildPermitted(self, childClassInfo, childInstance = None):        """            Returns if the specified child is permitted as a             child of the class' instances.                        NOTE: This is from this class' instance perspective.                        For component containers, this always overrides what the            return value from childClassInfo.isPermittedInContainer(...)        """                #DEFAULT RULE: AssessmentActions may only contain Actions        return childClassInfo.isInstanceOf('Action')        #---------------------------------------------------------------#

    def onConfigureProperties(self):        """            Automatically called by the Knowledge Engine once            the class has been loaded.  Use this method to register             class specific properties using the PropertyReflection interface.                        If this class is sub-classed, a call must be made to            the super-class to ensure super-class properties are            correctly registered                        NOTE: This method is called before ClassInfo.onAfterStartup()                    """
        #initialise the super-class properties for reflection        ElementInfo.onConfigureProperties(self)        #add the 'condition' (guard) property (which is a showif KERL)        self.addPropertyDefinition(PropertyDefinition(identity="condition", displayName="Condition", description="The KERL condition that must be true for the Assessment Action to be displayed and executed", defaultValue="", propertyType=pt_STRING, propertyFormat=pf_TEXT_SINGLELINE, propertyStructure=ps_ATOMIC))                #---------------------------------------------------------------#

    def onConfigureEvents(self):        """            Automatically called by the Knowledge Engine once            the class has been loaded.  Use this method to register             class specific events using the EventReflection interface.                        If this class is sub-classed, a call must be made to            the super-class to ensure super-class properties are            correctly registered                        NOTE: This method is called before ClassInfo.onAfterStartup()                    """                        #initialise the super-class events for reflection        ElementInfo.onConfigureEvents(self)
        #---------------------------------------------------------------#

    def onConfigurePermissions(self):        """            Automatically called by the Knowledge Engine once            the class has been loaded.  Use this method to register             class specific permission definitions.                        If this class is sub-classed, a call must be made to            the super-class to ensure super-class properties are            correctly registered                        NOTE: This method is called before ClassInfo.onAfterStartup()                    """
        #initialise the super-class permissions for reflection        ElementInfo.onConfigurePermissions(self)
        
        #add a definition for the 'ExecuteAssessmentAction' permission        self.addPermissionDefinition(PermissionDefinition(identity="ExecuteAssessmentAction", displayName="Execute Assessment Action", description="Permission to execute the Assessment Action", securableScope=SS_ALL, actorScope=AS_ALL, usesCredits=false, isCommencementPermitted=true, isExpiryPermitted=true, usesAssessmentScope=false))
        #---------------------------------------------------------------#        def getType(self):        """            Return the where the Action instances of this class            may be executed; at_SERVER and at_BROWSER are valid types            This is directly related to the Event types.  Action            types may be order together if they support multiple            locations of execution.        """                return at_SERVER
    #---------------------------------------------------------------#

####################################################################### AssessmentAction Class Definitionclass AssessmentAction(Element):    """        A class to represent an assessment action    """

    #---------------------------------------------------------------#
    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class    _CLASSINFO = AssessmentActionInfo()

    #---------------------------------------------------------------#    # Volatile Attributes    _v_Model = None             #the model to which the component belongs

    #---------------------------------------------------------------#

    def __init__(self, id, identity):        "Constructor for the AssessmentAction"        
        Element.__init__(self, id, identity)                #perform onAfterInstanciation processing        self.onAfterInstanciation()

    #---------------------------------------------------------------#

    def onAfterInstanciation(self):        """            Handle Knowledge Engine specific actions after this object             has been loaded into memory.                          This is useful for performing backwards compatibility        """                        #perform default processing        Element.onAfterInstanciation(self)
                    #---------------------------------------------------------------#

    def isDisplayedBeforeComponents(self):        """            Returns if the Element is to be displayed before            components in a model. Alternatively the Element is            displayed after the components in a model.            (If the element is in a model)        """                #AssessmentActions are displayed before         return false

    #---------------------------------------------------------------#

    def getModel(self):        """            Returns the Model in which this component is located.        """
        parent = self.getParent()                while not parent.isInstanceOf("Model"):            parent = parent.getParent()    
        return parent
            #---------------------------------------------------------------#    def isOrderedContainer(self):        """            Return if the children of the object may use ordering.                        This is to allow the 'Order' column in the Content            management tab in Zope                    """        return true             #---------------------------------------------------------------#        def getCondition(self):        """            Returns the KERL condition/guard        """                return self.condition             #---------------------------------------------------------------#        def isAvailable(self, assessment):        """            Returns if the Assessment Action is available for the specified            assessment.        """                #get the KERL         lConditionKERL = parseKERL(self.getCondition())        #get the closure for the KERL        lConditionKERL = getRuleShowIfTransitiveClosure(lConditionKERL, assessment.getModel(), assessment)        #does the condition evaluate to true?        return evaluate(lConditionKERL, assessment)            #---------------------------------------------------------------#        def execute(self, assessment, user = None, previousActionSuccess = true):        """            ABSTRACT: Attempts to execute the defined action             (on the SERVER), returning true if the action performed             some task or false if no tasks where executed/there was an error                        NOTE: The action is executed using the permissions of the            specified Knowledge Engine User.                        previousActionSuccess: specifies if the immediate action at the same level was successful.        """                            #is the action available for the provided assessment?        if self.isAvailable(assessment):            #get the actions for the event (in order)            actions = self.getChildrenByOrder()                        #(assume the last action was successful... at the start of a new container)            lLastActionSuccess = true                        for action in actions:                #execute the current action                lLastActionSuccess = action.execute(assessment, user, lLastActionSuccess)                            #(containers by default are always successfull at executing)            return true        else:            #not available so return false (we didn't execute it)            return false            #---------------------------------------------------------------#

####################################################################### Class Initialisation
# Register Class Information with the Knowledge EngineregisterGenericObjectClass(AssessmentAction)
#####################################################################
